package v2.structure.proxy.jdk;


import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;
import java.lang.reflect.Proxy;

/**
 * 通过JDK提供的代理工具来实现代理接口
 *
 * Proxy.newProxyInstance(ClassLoader loader, Class<?>[] interfaces, InvocationHandler h)
 *
 * 参数1: ClassLoader loader 接口使用的类加载器
 * 参数2: Class<?>[] interfaces 要代理的业务接口数组
 * 参数3: InvocationHandler h (接口)执行处理类，实现对所有接口的所有方法进行增强逻辑
 * 返回： 返回对象，可强制转换不同的接口
 *
 * @author : zhenyun.su
 * @since : 2023/10/12
 */

public class JdkProxy {

    public static void main(String[] args) {
        Buy buy = new BuySaleHouse();
        // 同时代理Buy和Sale接口
        Object proxy = Proxy.newProxyInstance(BuySaleHouse.class.getClassLoader(), new Class[]{Buy.class, Sale.class}, new BuyHouseInvocationHandler(buy));
        Buy buyHouse= (Buy)proxy;
        buyHouse.buy1();
        buyHouse.buy2();

        Sale saleHouse= (Sale)proxy;
        saleHouse.sale();
    }

    //定义代理方法的增强方法
    public static class BuyHouseInvocationHandler implements InvocationHandler{
        private Object o;

        public BuyHouseInvocationHandler(Object o) {
            this.o= o;
        }

        // 为newProxyInstance注册的所有接口的所有方法，执行invoke处理
        @Override
        public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
            System.out.println("买房前准备");
            // 重要提示：method方法使用对象，不要用proxy，用外部传入业务对象，会报错
            Object result = method.invoke(o, args);
            System.out.println("买房后装修");
            return result;
        }
    }
}

